package com.game.sdk.util;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import org.apache.commons.codec.binary.Base64;

import com.game.sdk.YTAppService;

import android.util.Log;

public class Encrypt {

	public static final String START_WORD = "z";
	public static final String END_WORD = "m";
	public static final String INSERT_WORD = "_";

	public static String encode(String str) {
		char[] k = YTAppService.k;

		if (str == null) {
			return "";
		}
		str = encodeStr(str);
		StringBuffer sb = new StringBuffer();
		char[] array = str.toCharArray();
		sb.append(START_WORD);
		for (int i = 0; i < array.length; i++) {
			sb.append(array[i] + k[((i + DataSafeUtil.code) % k.length)]);
			sb.append(INSERT_WORD);
		}
		sb.deleteCharAt(sb.length() - 1);
		sb.append(END_WORD);
		return sb.toString();
	}

	public static String decode(String str) {
		char[] k = YTAppService.k;
		if (str == null) {
			return null;
		}
		if ((str.startsWith(START_WORD)) && (str.endsWith(END_WORD))) {
			StringBuffer sb = new StringBuffer(str);
			sb.deleteCharAt(0);
			sb.deleteCharAt(sb.length() - 1);
			str = sb.toString();
			String[] strs = str.split(INSERT_WORD);
			sb = new StringBuffer();
			for (int i = 0; i < strs.length; i++) {
				sb.append((char) (Integer.parseInt(strs[i]) - k[((i + DataSafeUtil.code) % k.length)]));
			}

			return decodeStr(sb.toString());
		}
		return "";
	}

	public static String decode2(String str) {
		char[] k = YTAppService.k;
		if (str == null) {
			return null;
		}

		if ((str.startsWith("x")) && (str.endsWith("y"))) {
			StringBuffer sb = new StringBuffer(str);
			sb.deleteCharAt(0);
			sb.deleteCharAt(sb.length() - 1);
			str = sb.toString();
			String[] strs = str.split(INSERT_WORD);
			sb = new StringBuffer();
			for (int i = 0; i < strs.length; i++) {
				sb.append((char) (Integer.parseInt(strs[i]) - k[((i + DataSafeUtil.code) % k.length)]));
			}

			return decodeStr(sb.toString());
		}
		return "";
	}

	/**
	 * @param str
	 * @return
	 */
	public static String decodeStr(String str) {
		byte[] debytes = Base64.decodeBase64(new String(str).getBytes());
		return new String(debytes);
	}

	/**
	 * @param str
	 * @return
	 * @see [类、类#方法、类#成员]
	 */
	public static String encodeStr(String str) {
		byte[] enbytes = Base64.encodeBase64Chunked(str.getBytes());
		return new String(enbytes);
	}

	/**
	 * 数据压缩
	 * 
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public static byte[] compress(byte[] data) {
		try {
			ByteArrayInputStream bais = new ByteArrayInputStream(data);
			ByteArrayOutputStream baos = new ByteArrayOutputStream();

			// 压缩
			compress(bais, baos);

			byte[] output = baos.toByteArray();

			baos.flush();
			baos.close();
			bais.close();

			return output;
		} catch (Exception e) {
			Logger.msg("数据压缩异常！");
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 数据压缩
	 * 
	 * @param is
	 * @param os
	 * @throws Exception
	 */
	public static void compress(InputStream is, OutputStream os)
			throws Exception {
		GZIPOutputStream gos = new GZIPOutputStream(os);
		int count;
		byte data[] = new byte[1024];
		while ((count = is.read(data, 0, data.length)) != -1) {
			gos.write(data, 0, count);
		}
		// gos.flush();
		gos.finish();
		gos.close();
	}

	/***
	 * 对于网络的数据怎么去解读，是否处理压缩，是否处理解密
	 * 
	 * @author ling
	 * @param in
	 *            网络输入
	 * @param isEncode
	 *            标识是否加密
	 * @param isZip
	 *            是否压缩
	 * @return 在处理网络留出现错误的时候，出现 string =""或者null;
	 * */
	public static String readNetStream(InputStream in, boolean isEncode,
			boolean isZip) {
		String temp = "";
		if (isZip) {
			temp = unzip(in);
		} else {
			temp = readFromNetStream(in);
		}
		if (isEncode) {
			temp = decode(temp);
		}
		return temp;
	}

	/**
	 * @param request
	 *            网络的输入流
	 * @缘由 不需要解压缩 zip 直接用json格式
	 * 
	 * */
	public static String readFromNetStream(InputStream request) {
		try {
			byte[] buffer = new byte[1024];
			int num = 0;
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			while (-1 != (num = request.read(buffer))) {
				bos.write(buffer, 0, num);
			}
			return bos.toString("utf-8");
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 数据解压
	 */
	public static String unzip(InputStream in) {
		// Open the compressed stream

		GZIPInputStream gin;
		try {
			if (in == null) {
				Logger.msg("没有输入流========");
				return null;
			}
			gin = new GZIPInputStream(new BufferedInputStream(in));
			Log.i("kd", "文件解压中1。。。");

			ByteArrayOutputStream out = new ByteArrayOutputStream();
			// Transfer bytes from the compressed stream to the output stream
			byte[] buf = new byte[1024];
			int len;
			while ((len = gin.read(buf)) > 0) {
				out.write(buf, 0, len);
			}
			// Logger.msg("文件解压中2。。。");
			// Close the file and stream
			gin.close();
			out.close();
			String str_result = new String(out.toByteArray());
			// Logger.msg("service back data:" + str_result);
			// Logger.msg("service Encrypt data:" + Encrypt.decode(str_result));
			return str_result;
		} catch (IOException e) {
			Logger.msg("解压文件异常:" + e.getMessage());
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * @author ling
	 * @param request
	 *            请求
	 * @param isEncode
	 *            请求是否加密
	 * @param isZip
	 *            请求 是否压缩
	 * @return entityBytes返回一个字节数组
	 * */
	public static byte[] computeData(String request, boolean isEncode,
			boolean isZip) {
		byte[] entityBytes = null;
		if (isEncode) {
			request = Encrypt.encode(request);
		}
		if (isZip) {
			entityBytes = Encrypt.compress(request.getBytes());
		}
		return entityBytes;
	}

}
